package com.biodiv.miracle.web.context;

import com.biodiv.miracle.event.core.EventSourceManager;
import com.biodiv.miracle.ioc.BeanDefinition;
import com.biodiv.miracle.ioc.context.GeneralApplicationContext;
import com.biodiv.miracle.ioc.factory.DefaultBeanFactory;
import com.biodiv.miracle.ioc.processor.BeanPostProcessor;
import com.biodiv.miracle.support.utils.MiracleUtils;
import com.biodiv.miracle.web.handler.DefaultHandler;
import com.biodiv.miracle.web.listener.ContextRefreshedErrorListener;
import com.biodiv.miracle.web.listener.ServletInitEventListener;
import com.biodiv.miracle.web.server.TomcatServer;
import com.biodiv.miracle.web.server.WebServer;
import com.biodiv.miracle.web.servlet.DispatcherServlet;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

/**
 * @Author: tianquan
 * @CreateTime: 2025-05-26  09:13
 * @Description: web server application context
 */
public class ServletWebServerApplicationContext extends GeneralApplicationContext {

    private final Logger logger = Logger.getLogger(ServletWebServerApplicationContext.class.getName());
    protected List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
    protected List<Class<?>> autoConfigurationBeans = new ArrayList<>();
    protected WebServer webServer;
    protected DispatcherServlet dispatcherServlet;

    public ServletWebServerApplicationContext(Class<?> clazz, String[] args) {
        this.clazz = clazz;
        this.args = args;
    }

    @Override
    public void refresh() {
        webStart();
        // 初始化容器
        super.refresh();
    }

    private void webStart() {
        BeanDefinition beanDefinition = new BeanDefinition("dispatcherServlet", DispatcherServlet.class, "singleton");
        beanFactory.registerBeanDefinition("dispatcherServlet", beanDefinition);
        dispatcherServlet = beanFactory.getBean(DispatcherServlet.class);
        webServer = new TomcatServer(dispatcherServlet);
        String port = getEnvironmentVariable("server.port");
        if (port != null) {
            webServer.setPort(Integer.parseInt(port));
        }
        webServer.start();
    }

    @Override
    protected void preBeanPostProcessor(DefaultBeanFactory beanFactory) {
        super.preBeanPostProcessor(beanFactory);
        beanFactory.getBeanPostProcessors().addAll(beanPostProcessors);
    }

    @Override
    protected void registerListeners(EventSourceManager eventSourceManager) {
        super.registerListeners(eventSourceManager);
        eventSourceManager.addEventListener(new ServletInitEventListener());
        eventSourceManager.addEventListener(new ContextRefreshedErrorListener(this));
    }

    @Override
    protected void preBeanInitialization(DefaultBeanFactory beanFactory) {
        autoConfigurationBeans.add(DefaultHandler.class);
        for (Class<?> aClass : autoConfigurationBeans) {
            String beanName = MiracleUtils.createBeanName(aClass);
            // 需要生成Bean定义对象
            BeanDefinition beanDefinition = new BeanDefinition(beanName, aClass, "singleton");
            // 向容器中添加Bean定义对象
            beanFactory.registerBeanDefinition(beanName, beanDefinition);
            // 获取Bean
            beanFactory.getBean(aClass);
        }
    }

    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        beanPostProcessors.add(beanPostProcessor);
    }

    public void addAutoConfigurationBeans(Class<?> autoConfigurationBean) {
        autoConfigurationBeans.add(autoConfigurationBean);
    }


    public void initDispatcherServlet() {
        dispatcherServlet.init();
    }

    public void stop() {
        webServer.stop();
    }
}
